package com.minelx.datamicroscope.core.values;

import com.alibaba.fastjson.JSONObject;
import com.minelx.datamicroscope.common.CommonDatabase;
import com.minelx.datamicroscope.common.CommonDatabases;
import com.minelx.sqlstructures.core.ColumnType;
import com.minelx.sqlstructures.core.table.ITable;
import com.minelx.sqlstructures.core.values.FieldValues;
import com.minelx.sqlstructures.statements.clause.Conditions;
import com.minelx.sqlstructures.statements.clause.Field;
import com.minelx.sqlstructures.statements.clause.Sql;

import java.util.List;
import java.util.Objects;

import static java.util.stream.Collectors.joining;

public final class CommonField {
	private final CommonTable commonTable;

	private final String name;

	CommonField(CommonTable commonTable, String name) {
		this.commonTable = commonTable;
		this.name = name;
	}

	public String path() {
		return String.format("%s.%s", commonTable.path(), name);
	}

	public Sql inCondition(List<String> values) {
		// fetch column type
		ColumnType columnType = ColumnType.from(structure().getType());
		return Conditions.in(name(), values.stream()
				.map(columnType::representAsSql)
				.collect(joining(",")));
	}

	public Field toSqlField() {
		return Field.of(name);
	}

	public FieldValues structure() {
		ITable table = commonTable().commonDatabase().structure().table(commonTable().name());
		return table.getFields().stream()
				.filter(which -> which.getName().equals(name))
				.findFirst().orElseThrow(() -> new RuntimeException("can't find field '" + name + "' in " + commonTable.path()));
	}

	public String name() {
		return name;
	}

	public CommonTable commonTable() {
		return commonTable;
	}

	public static CommonField from(String pattern) {
		String[] segments = pattern.split("\\.");
		if (segments.length != 2) {
			throw new IllegalArgumentException("wrong field locate pattern: " + pattern);
		}
		return CommonTable.from(segments[0]).field(segments[1]);
	}

	public static CommonField from(JSONObject data) {
		return CommonTable.from(data)
				.field(data.getString("field"));
	}

	public static CommonField newpay(String table, String field) {
		CommonDatabase database = CommonDatabases.create("2", "newpay");
		return CommonTable.create(database, table).field(field);
	}


	@Override
	public boolean equals(Object o) {
		if (this == o) return true;
		if (o == null || getClass() != o.getClass()) return false;
		CommonField that = (CommonField) o;
		return commonTable.equals(that.commonTable) && name.equals(that.name);
	}

	@Override
	public int hashCode() {
		return Objects.hash(commonTable, name);
	}

	@Override
	public String toString() {
		return "CommonField{" +
				"commonTable=" + commonTable +
				", name='" + name + '\'' +
				'}';
	}
}
